﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Reflection;
namespace System.Data.Services.Providers
{
    /// <summary>
    /// Represents a strongly typed service that can process data-oriented 
    /// resource requests that use EntityFramework for building the data model.
    /// </summary>
    /// <typeparam name="T">The type of the store to provide resources.</typeparam>
    public abstract class EntityFrameworkDataService<T> : DataService<EntityFrameworkDataServiceProvider2<T>> where T : DbContext, new()
    {
        /// <summary>
        /// Cached instance of the data source.
        /// </summary>
        private EntityFrameworkDataServiceProvider2<T> dataSource;
        /// <summary>
        /// Returns an instance of EntityFrameworkDataServiceProvider2 as the data source
        /// </summary>
        /// <returns>Instance of EntityFrameworkDataServiceProvider2</returns>
        protected override EntityFrameworkDataServiceProvider2<T> CreateDataSource()
        {
            if (this.dataSource == null)
            {
                this.dataSource = new EntityFrameworkDataServiceProvider2<T>(new DataServiceProviderArgs(this, Activator.CreateInstance<T>(), EntityFrameworkDataService<T>.GetKnownTypes(), false));
            }
            return this.dataSource;
        }
        /// <summary>
        /// Returns the types that exist on the given context by using reflection
        /// </summary>
        /// <returns>List of types that exist on the given context</returns>
        private static List<Type> GetKnownTypes()
        {
            List<Type> list = new List<Type>();
            PropertyInfo[] properties = typeof(T).GetProperties();
            PropertyInfo[] array = properties;
            for (int i = 0; i < array.Length; i++)
            {
                PropertyInfo propertyInfo = array[i];
                if (propertyInfo.PropertyType == typeof(DbSet))
                {
                    list.Add(propertyInfo.PropertyType.GetGenericArguments()[0]);
                }
            }
            return list;
        }
    }
}
